package com.rd.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rd.common.CommonResult;
import com.rd.common.vo.GrantRoleFormData;
import com.rd.common.vo.PageBean;
import com.rd.common.vo.UpdateAvatarFormData;
import com.rd.common.vo.UpdatePwdFormData;
import com.rd.mapper.SysRoleMapper;
import com.rd.mapper.SysUserRoleMapper;
import com.rd.pojo.SysRole;
import com.rd.pojo.SysUser;
import com.rd.pojo.SysUserRole;
import com.rd.service.SysRoleService;
import com.rd.service.SysUserRoleService;
import com.rd.service.SysUserService;
import com.rd.util.QiniuOssUtil;
import com.rd.util.ResultUtil;
import com.rd.util.UploadUtil;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

@RestController
@RequestMapping("/sys/user")
@Slf4j
public class SysUserController {

    @Resource
    SysUserService sysUserService;

    //@RequestBody传递json数据
    //@PreAuthorize("hasAuthority('system:user:edit')")拥有编辑用户的权限才能修改
    @PostMapping("/updateBaseInfo")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public CommonResult updateBaseInfo(@RequestBody SysUser sysUser) {
        sysUser.setUpdateTime(new Date());
        int n = sysUserService.updateBaseInfo(sysUser);
        return n > 0 ? ResultUtil.buildSuccess("修改成功!") : ResultUtil.buildError("修改失败!");
    }

    /**
     * get请求， 请求地址上有2个参数，用户id和用户输入的旧密码
     */
    @GetMapping("/checkOldPwd/{userId}/{oldPassword}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public CommonResult checkOldPwd(@PathVariable("userId") Long userId, @PathVariable("oldPassword")
            String oldPassword) {
        log.info("验证旧密码:{}", oldPassword);
        //根据用户id获取用户信息  getById是MybatisPlus自己提供方法，根据id获取用户信息
        SysUser sysUser = sysUserService.getById(userId);
        //获取到sys_user表中存储的密码$2a$10$Kib4zuVhTzg3I1CoqJfd0unuY9G9ysI7cfbhyT3fi7k7Z
        String dataBasePwd = sysUser.getPassword();
        //密码加密工具BCryptPasswordEncoder 是spring security框架提供的加密工具
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean flag = bCryptPasswordEncoder.matches(oldPassword, dataBasePwd);
        return flag ? ResultUtil.buildSuccess("旧密码正确") : ResultUtil.buildError("旧密码错误！");
    }

    @PostMapping("/updatePwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public CommonResult updatePwd(@RequestBody UpdatePwdFormData pwdForm) {
        int n = sysUserService.updatePwd(pwdForm);
        return n > 0 ? ResultUtil.buildSuccess("修改成功!") : ResultUtil.buildError("修改失败!");
    }

    @PostMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public CommonResult uploadImage(MultipartFile file) throws Exception {
//        Map<String,Object> map=new HashMap<>();
        if (Objects.nonNull(file)) {
            //如果上传目录为/static/images/upload/，则可以如下获取：
            File path = new File(ResourceUtils.getURL("classpath:").getPath());
            if (!path.exists()) {
                path = new File("");
            }
            System.out.println("path:" + path.getAbsolutePath());
            File dir = new File(path.getAbsolutePath(), "static/images/upload/");
            if (!dir.exists()) {
                dir.mkdirs();
            }
            System.out.println("upload url:" + dir.getAbsolutePath());
            File destFile = new File(dir, UploadUtil.saveFile(file, dir.getAbsolutePath()));
            String qiNiuPath = new QiniuOssUtil().upload(destFile);
            //向前端传递值
            Map<String, Object> map = new HashMap<>();
            map.put("code", 0);
            map.put("msg", "图片上传成功");
            map.put("qiNiuPath", qiNiuPath);
            log.info("上传成功以后的地址:{}", qiNiuPath);
            return ResultUtil.buildSuccess(map);
        }
        return ResultUtil.buildError(-1, "文件上传失败!");
    }


    @PostMapping("/updateAvatar")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public CommonResult updateAvatar(@RequestBody UpdateAvatarFormData avatarForm) {
        int n = sysUserService.updateAvatar(avatarForm);
        return n > 0 ? ResultUtil.buildSuccess("修改成功!") : ResultUtil.buildError("修改失败!");
    }

    @Resource
    SysRoleMapper sysRoleMapper;

    @PostMapping("/list")
        /**拥有查询权限才可以访问方法*/
    @PreAuthorize("hasAuthority('system:user:query')")
    public CommonResult userList(@RequestBody PageBean pageBean) {
        //mybatis-plus提供一个page方法帮助分页
        // import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
        Page<SysUser> page = new Page<>
                (pageBean.getPageNum(), pageBean.getPageSize());

        //新增一个查询条件
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        String queryValue = pageBean.getQuery().trim();
        log.info("queryValue={}", queryValue);
        //like是模糊查询  where username like '%queryValue%'
        queryWrapper.like(!StringUtil.isNullOrEmpty(queryValue), "username", queryValue);

        IPage<SysUser> iPage = sysUserService.page(page, queryWrapper);
        List<SysUser> userList = iPage.getRecords();
        for (SysUser sysUser : userList) {
            List<SysRole> roleList = sysRoleMapper.selectRoleByUserId(sysUser.getId());
            sysUser.setSysRoleList(roleList);
        }
        long total = iPage.getTotal();
        Map<String, Object> map = new HashMap<>();
        map.put("userList", userList);
        map.put("total", total);
        return ResultUtil.buildSuccess(map);
    }


    @PostMapping("/addUser")
    @PreAuthorize("hasAuthority('system:user:add')" + "||" + "hasAuthority('system:user:edit')")
    public CommonResult addUser(@RequestBody SysUser sysUser) {
        if (StringUtil.isNullOrEmpty(String.valueOf(sysUser.getId())) || sysUser.getId() == -1) {
            //新增
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            sysUser.setPassword(encoder.encode(sysUser.getPassword()));
            sysUser.setCreateTime(new Date());
            sysUser.setAvatar("http://qff-oss.softeem.xin/192de9a8-5760-4268-a4fd-644c1430a7d9.jpg");
            boolean flag = sysUserService.save(sysUser);
            return flag ? ResultUtil.buildSuccess("添加成功!") : ResultUtil.buildError("添加失败!");
        } else {
            sysUser.setUpdateTime(new Date());
            boolean flag = sysUserService.updateById(sysUser);
            return flag ? ResultUtil.buildSuccess("修改成功!") :
                    ResultUtil.buildError("修改失败!");
        }
    }

    /*验证用户名是否重复*/
    @GetMapping("/checkUserName/{username}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public CommonResult checkUserName(@PathVariable("username") String username) {
        SysUser sysUser = sysUserService.getUserByName(username);
        return sysUser == null ? ResultUtil.buildSuccess("此用户名可以使用") :
                ResultUtil.buildError("此用户名已经被注册");
    }

    /*3> 验证手机号是否重复*/
    @GetMapping("/checkUserPhone/{userPhone}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public CommonResult checkUserPhone(@PathVariable("userPhone") String userPhone) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phonenumber", userPhone);
        SysUser sysUser = sysUserService.getOne(queryWrapper);
        return sysUser == null ? ResultUtil.buildSuccess("此手机号码可以使用!") :
                ResultUtil.buildError("此手机号码已经被注册!");
    }

    /*根据用户id获取用户详细信息*/
    @GetMapping("/getUser/{userId}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public CommonResult getUser(@PathVariable("userId") Long userId) {
        SysUser sysUser = sysUserService.getById(userId);
        return ResultUtil.buildSuccess(sysUser);
    }

    @Resource
    SysUserRoleService sysUserRoleService;

    @Transactional
    @PostMapping("/deleteUser")
    @PreAuthorize("hasAuthority('system:user:delete')")
    public CommonResult deleteUser(@RequestBody Long[] ids) {
        log.info("需要逻辑删除用户id:{}", Arrays.toString(ids));
        //先从 sys_user_role表中删除这个用户记录
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        // where user_id in(1,2,3)
        queryWrapper.in("user_id", ids);
        sysUserRoleService.remove(queryWrapper);
        //再删除 sys_user表中的数据
        sysUserService.removeByIds(Arrays.asList(ids));
        return ResultUtil.buildSuccess("删除成功");
    }

    @Transactional
    @PostMapping("/grantRole")
    @PreAuthorize("hasAuthority('system:user:role')")
    public CommonResult deleteUser(@RequestBody GrantRoleFormData formData){
        log.info("formData={}",formData);
        //先删除这个用户角色delete from sys_user_role where user_id=?
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id",formData.getId()));
        //批量插入
        List<SysUserRole> list = new ArrayList<>();
        if (Objects.nonNull(formData.getCheckedRoles())){
            for (Long roleId:formData.getCheckedRoles()){
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(formData.getId());
                sysUserRole.setRoleId(roleId);
                list.add(sysUserRole);
            }
        }
        sysUserRoleService.saveBatch(list);
        return ResultUtil.buildSuccess("角色分配成功");
    }

    @GetMapping("/updateState/{userId}/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public CommonResult updateState(
            @PathVariable("userId")Long userId,
            @PathVariable("status")String status
    ){
        //根据id找到sysuser对象
        SysUser sysUser = sysUserService.getById(userId);
        sysUser.setStatus(status);
        sysUser.setUpdateTime(new Date());
        boolean flag = sysUserService.updateById(sysUser);
        return flag?ResultUtil.buildSuccess("状态更新成功!"):
                ResultUtil.buildError("状态更新失败!");
    }


}
